package com.txw.javaCore.server.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.txw.javaCore.api.response.BaseResponse;
import com.txw.javaCore.api.response.StatusCode;
import com.txw.javaCore.model.entity.Item;
import com.txw.javaCore.model.mapper.ItemMapper;
import com.txw.javaCore.server.service.BatchDataService;
import com.txw.javaCore.server.util.ExcelUtil;
import com.txw.javaCore.server.util.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.List;


/**
 * @PROJECT_NAME: JavaCoreB2
 * @DESCRIPTION:
 * @Author: 涂玄武
 * @DATE: 2020/12/25 10:30
 */
@Controller
@RequestMapping(value = "excel")
public class ExcelController extends BaseController {

    @Autowired
    private Environment env;

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private BatchDataService batchDataService;

    /**
     * 预批量生成百万级别数据
     *
     * @return
     */
    @RequestMapping(value = "batch/data/insert")
    @ResponseBody
    public BaseResponse batchInsertData(@RequestParam Integer times) {
        log.info("--前端接受的请求参数：{}", times);
        BaseResponse response = new BaseResponse(StatusCode.Success);
        try {
            //times为批量插入数据的次数，每次数据量为 Constant.batchDataSize
            batchDataService.batchInitItem(times);
        } catch (Exception e) {
            log.error("预批量生成百万级别数据-发生异常：{}", e.getMessage());
            response = new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
        }
        return response;
    }

    /**
     * POI方式导出Excel（耗时，耗费内存，会出现内存溢出情况）
     * 1、确定需要导出的数据库表以及字段名-充当Excel头部字段名列表
     * 2、查询获取符合条件的数据列表
     * 3、根据确定的字段以及数据列表构造list<map<key-value>>
     * 4、最终将构造好的数据写入Excel的sheet中
     *
     * @param search
     * @param httpServletRequest
     * @param httpServletResponse
     * @return
     */
    @RequestMapping(value = "poi/export")
    @ResponseBody
    public String exportData(String search, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        log.info("--前端接受的请求参数：{}", search);
        //获取待下载的数据-将数据塞入到excel表格中的sheet里去-将excel文件存到某个文件目录-下载到浏览器
        //方式一
        //List<Item> list = itemMapper.selectAll(search);
        //方式二
        List<Item> list = batchDataService.getDataPOI(search);

        //SAX模式
        ExcelUtil util = new ExcelUtil(Item.class);
        String fileName = util.exportExcel(list, env.getProperty("item.download.file.name"));

        String downFile = util.getAbsoluteFile(fileName);
        log.info("待下载的文件名：{}，文件所在的路径：{}", fileName, downFile);

        //将Excel文件读取出来，走网络传输给浏览器下载
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("multipart/form-data");
        //attachment：指定文件为附件，并对文件名重新进行编码
        httpServletResponse.setHeader("Content-Disposition", "attachment;fileName=" + FileUtils.setFileDownloadHeader(httpServletRequest, fileName));
        FileUtils.writeBytes(downFile, httpServletResponse.getOutputStream());
        return fileName;
    }

    /**
     * easyExcel方式导出Excel（针对大数据量）
     *
     * @param search
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "easy/excel/export")
    @ResponseBody
    public String exportDataV2(String search, HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取Excel文件名
        String fileName = env.getProperty("item.download.file.name") + System.currentTimeMillis() + ExcelTypeEnum.XLS.getValue();
        ExcelWriter excelWriter = EasyExcel.write(env.getProperty("item.download.file.root.path") + fileName).build();

        //获取待插入excel工作表中的数据
        //一个 List<Item> 对应着一个工作表sheet
        //所有的 List<Item>，即 List<List<Item>> 就代表着一个excel文件
        List<List<Item>> list = batchDataService.getDataV2(search);
        WriteSheet writeSheet;
        for (int i = 0; i < list.size(); i++) {
            writeSheet = EasyExcel.writerSheet(i,"表"+i).head(Item.class).build();
            excelWriter.write(list.get(i),writeSheet);
        }
        //关闭流
        if (excelWriter != null){
            excelWriter.finish();
        }

         //将Excel文件获取出来，同时走网络传输进行下载
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition","attachment;fileName="+FileUtils.setFileDownloadHeader(request,fileName));
        FileUtils.writeBytes(env.getProperty("item.download.file.root.path")+fileName,response.getOutputStream());
        return fileName;
    }

}
